// promisify函数作用就是把 callback 形式转成 promise 形式。
const { promisify } = require("util") 
// 封装一个函数，得到一个函数，得到的函数返回值是一个promise
const download = promisify(require("download-git-repo"))
const path = require("path");
const rimraf = require("rimraf");
const ejs = require('ejs');
const shell = require("shelljs")
// 可视加载
const ora = require('ora') 
// 交互
const inquirer = require("inquirer")
// 仓库地址映射
const repoMap = require("../config/repoMap") 

const fs = require("fs")

const useTemplate = () => {
  return inquirer.prompt([
    {
      type: "list",
      name: "template",
      message: "chose template:",
      default: 0,
      choices: [
        { value: 0, name: "EmptyVueTemplate" },
        { value: 1, name: "Vue3Admin" },
        // { value: 1, name: "zzg-cli" }
      ]
    }
  ])
}

const usePackage = () => {
  return inquirer.prompt([
    {
      type: "list",
      name: "package",
      message: "chose package:",
      default: 0,
      choices: [
        { value: "npm", name: "npm" },
        { value: "yarn", name: "yarn" }
      ]
    }
  ])
}

const useVersion = () => {
  return inquirer.prompt([
    {
      type: 'input',
      name: 'version',
      default: '1.0.0',
      message: 'project version:'
    }
  ])
}

const useDescription = () => {
  return inquirer.prompt([
    {
      type: 'input',
      name: 'description',
      default: ' ',
      message: 'project description:'
    }
  ])
}

const useAutuor = () => {
  return inquirer.prompt([
    {
      type: 'input',
      name: 'author',
      default: ' ',
      message: 'project author:'
    }
  ])
}



const getResult = async ()=> {
  const descriptionRes = await useDescription()
  const versionRes = await useVersion()
  const authorRes = await useAutuor()
  const templateRes = await useTemplate()
  const packageRes = await usePackage()
  return {
    version: versionRes.version,
    author: authorRes.author,
    template: templateRes.template,
    package: packageRes.package,
    description: descriptionRes.description
  }
}

const editPackageJson = (dir, result, projectName) => {
  let pathName = path.join(dir, "package.json")
  fs.readFile(pathName,'utf8', function (err, data){
    if (err) throw err;
    let json = JSON.parse(data);
    json.name = projectName
    json.version = result.version
    json.author = result.author
    json.description = result.description
    let newContent = JSON.stringify(json, null, 2);
    fs.writeFile(pathName, newContent, 'utf8', (err) => {
      if (err) throw err;
    });
  })
}

const renderIndexHTML = (dir, projectName) => {
  let pathName = path.join(dir, "index.html")
  ejs.renderFile(pathName, {projectName: projectName}, (err, result) => {
    if (err) throw err;
    fs.writeFileSync(pathName, result);
  })
}

const createProjectAction = async (projectName) => {
  const dir = path.join(process.cwd(), projectName);
  rimraf.sync(dir, {});
  const result = await getResult()
  const spinner = ora('downloading...').start(); // 开始可视加载
  await download(repoMap[result.template], projectName, { clone: true }).then(() => {
    spinner.succeed("download success!")

    const install = ora(`${result.package} installing...`).start(); // 开始可视加载
    editPackageJson(dir, result, projectName)
    renderIndexHTML(dir, projectName)
    shell.rm('-rf', `${projectName}/.git`)
    shell.cd(projectName)
    shell.exec(`${result.package} install`)
    install.succeed("install success!")
    console.log(`- cd ${projectName}`)
    console.log(`- npm start   -- to start project`)
  }).catch((error)=>{
    spinner.fail("error!",error)			// 结束可视加载
 })
}

module.exports = createProjectAction
